



//    类和对象

//创建一个类(大驼峰)
class Person{
//    类里面保护 字段-/属性-/成员变量（可以通过引用来访问）   字段定义在类的内部 方法的外部
//    成员变量 可以分为两种1.普通成员变量 2.静态成员变量  这里是普通的成员变量
    public String name;//不建议在这里初始化 类可以理解为模板 而我们是要去使用模板
//    这种类可以多人使用 如果一些地方不能随意修改 （例如如果有人在用的使用想将name修改为myName 这样之后的人如果继续调用name 那么就会出错） 所以就可以使用private修饰
    private  String name1;//（这里用name1来代替name 不然下面的代码有些因为name是被public修饰的） 所以我再创建一个Demo3来书写
    // 如果属性或者方法被private修饰  那么这个属性（name1）或者方法就被封装起来了 意味着只能在当前类当中使用它 在main8  256行


    public int age;

//    静态成员变量 也被称为类变量 这里被static修饰的变量会被存放在方法区 区别于栈和堆的第三块  内存
//    在方法区中 还放有.class文件（字节码文件）
//    不依赖与对象 就是可以通过  类.静态成员变量来访问（Person.count）
    public static int count;//在main3里



    public final int SIZE = 10;//被final修饰的叫常量，也属于对象。 被final修饰，后续不可更改   存放在对象（堆）当中
    public static final int COUNT = 99;//静态的常量，属于类本身，只有一份 被final修饰，后续不可更改 存放在方法区
//    一个对象 存储到哪里 和你是否被final修饰没有关系




//    成员方法->行为  （可以通过引用来访问）
//    成员方法 可以分为两种1.普通成员方法 2.静态成员方法
//    当调用成员方法时 会在栈上占用一块内存
    public void eat(){
        System.out.println(name + "正在吃饭");
//        static int size = 2000; static
//        报错 在普通成员方法不能创建静态成员变量
//        在static前面加个public 也是不可以的

//        在普通方法不能调用静态成员变量 为什么？
//        1.static定义的变量是类变量 属于类的
//        2.eat方法的调用 需要对应的引用来调用 但是如果定义的static的变量 Person就可以直接调用
//        总结：静态的成员变量是不可以在方法中定义的
    }


    public void sleep(){
//        在普通方法里面能不能调用静态方法  可以可以调用        调用调用调用不是定义
//        staticFunc();
//        相反在静态类方法内部不可以调用普通方法   （主要是静态的方法是不依赖于对象的）重要
        System.out.println(name + "正在睡觉");

    }


//    静态类方法  也是一样通过  类.静态方法来访问 Person.staticFunc()
    public static void staticFunc(){
        System.out.println("staticFunc");

//        sleep();这个会报错   静态类方法内部不可以调用普通方法

//        看这个看这个看这个  静态方法里面只能调静态方法
//        staticFunc1();这个家伙不会报错

    }
    public static void staticFunc1(){
        System.out.println("sqwedsa");
    }



//      1.
//    public String toString(){
//        return "姓名：" + name + " 年龄：" + age;
//    }

//      2.
//    鼠标右键点Generate-》点toString-》全选（shift/Ctrl ＋鼠标左键点击）-》点ok
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", SIZE=" + SIZE +
                '}';
    }
}


//代码开始
public class demo2 {

    public static void main1(String[] args) {
//        一个类可以实例化多个对象
        Person person = new Person();
        Person person1 = new Person();
        Person person2 = new Person();
        Person person3 = new Person();
        Person person4 = new Person();

//        在这里 person是一个变量 不是地址 只不过这个变量 里面存储的是地址 所以这个变量也被叫做引用
    }







    public static void main2(String[] args) {
        Person person = new Person();//person在栈上
        person.name = "lcw";
//        普通成员变量的访问需要通过对象的引用来访问的
        System.out.println(person.name);//有赋值 如果没有赋值结果为null
        System.out.println(person.age);//没有赋值 结果为0
//        这里的 null 和 0 是数据基本类型里的默认值 针对的是成员变量 如果成员变量没有赋初始值 就使用默认值

        System.out.println("=================");
//        每个对象都有name 和 age
        Person person1 = new Person();
        System.out.println(person1.name);
        System.out.println(person1.age);

    }





    public static void main3(String[] args) {
        Person person1 = new Person();
        person1.name = "lcw";
        person1.age = 18;
        System.out.println("========对类进行访问=========");
        System.out.println(person1.name);
        System.out.println(person1.age);
        person1.eat();
        person1.sleep();




        System.out.println("===对于普通成员变量访问=====");
        person1.age++;
        System.out.println("person1.age:" + person1.age);//19

        Person person2 = new Person();//创建新的对象person2
        person2.age++;
        System.out.println("person1.age:" + person2.age);// 1  因为没有初始化 age默认值为0






//        这里person1.count这些会报警告 这是因为 我们可以直接通过
//        类.静态成员变量来访问（Person.count）
        System.out.println("=======静态成员变量访问===对penson1访问=====");
        person1.count = 2000;
        System.out.println("count:" + person1.count);//可以打印出  2000

        System.out.println("========在这里再创建一个person2=======");
        person2.count++;
        System.out.println("count:" + person2.count); //结果变为2001了

        System.out.println("=======使用Person.count访问==========");
        System.out.println(Person.count);

        System.out.println("======使用Person.staticFunc()访问======");
        Person.staticFunc();
    }










    public static void func(){

    }//静态成员方法

    public void func2() {

    }//普通成员方法

    public static void main4(String[] args) {
        func();//可以直接调用
//        func2();不可以直接调用 但可以创建一个对象再调用
        demo2 demo2 = new demo2();
        demo2.func2();


//        问：main函数为什么是静态的？？
//        首先main函数 是不是静态的都可以 这个取决于JVM的实现方式
    }


    public static void main5(String[] args) {
        Person person = null;//1.表示这个引用 不指向任何的对象

        Person person1 = new Person();
        Person person2 = person1;//2.表示person2这个引用 指向person1这个引用所指向的对象

        Person person3 = new Person();
        person3 = new Person();
        person3 = new Person();
        person3 = new Person();
        person3 = new Person();//3.一个引用不可以同时指向多个对象（person3真正指向的是最后一次）
    }



//      4.引用一定是在栈上吗 肯定不是
//      也有可能在堆上
    Person person = new Person(); //这个在类内部 方法的外部

    public static void main6(String[] args) {
        demo2 demo = new demo2();
//        这里的demo是局部变量 内存在栈上(z1 设地址0x999)
//        因为new demo2()一个对象 这个对象内存在堆上(t1 0x999)
//        因为person属于demo2这个类的成员变量 所以会在 t1 内分配一块内存 (p1 0x888)
//        因为new Person()这里又创建一个对象 会在堆上再占一块内存 (t2 0x888)
    }









    public static void main7(String[] args) {
        Person person = new Person();
        System.out.println(person); //结果是 Person@1b6d3586
//        通过Ctrl+鼠标左键 一直点可以看到打印逻辑的源码 其实最后就相当于打印了toString方法的内容
//        println》valueOf》toString》
//        public String toString() {
//            return getClass().getName() + "@" + Integer.toHexString(hashCode());
//        }

//        注 但如果我们在Person这个类中创建一个toString的方法 那么会优先调用改方法 第69行左右 先注释掉了
//        所以我们可以这样用 我们可以return “姓名：” + name + “年龄：” + age;
//        这样我们通过这个System.out.println(person);可以直接打印出直接想要的内容
//        这里也有快捷键一键生成 76行左右
    }





    public static void main(String[] args) {

    }






}
